package com.example.base.util;

import lombok.extern.slf4j.Slf4j;
import sun.misc.ClassLoaderUtil;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class URLClassLoaderUtils {

    private static final Map<String,URLClassLoader> CLASS_LOADER_MAP=new ConcurrentHashMap<>();

    /**
     * 主系统的classLoader
     */
    private static ClassLoader CLASS_LOADER;

    public static void init(ClassLoader classLoader){
        CLASS_LOADER=classLoader;
    }


    /**
     * 动态加载本地jar，初始化类加载器
     */
    private static void loadJar(String jarPath) {
        URL url = null;
        File jarFile=null;
        try {
            // 加载本地jar
            jarFile= new File(jarPath);
            // 如果不存在该文件
            if(!jarFile.exists()){
                log.info("指定加载的jar不存在, jarPath:" + jarPath);
                return;
            }
            url = jarFile.toURI().toURL();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        File file=new File(jarPath);
        String fileName=file.getName();
        if(!CLASS_LOADER_MAP.containsKey(fileName)){
            AppClassLoader classLoader=new AppClassLoader(new URL[]{url},CLASS_LOADER);
            CLASS_LOADER_MAP.put(fileName,classLoader);
        }
    }



    /**
     * 重新加载jar
     * @param newJarPath
     */
    public static void reloadJar(String newJarPath){
        // 卸载当前jar
        unloadJar(newJarPath);
        // 重新加载新的jar
        loadJar(newJarPath);
    }

    /**
     * 卸载当前jar
     */
    public static void unloadJar(String jarPath){
        File file=new File(jarPath);
        String name=file.getName();
        if(CLASS_LOADER_MAP.containsKey(name)){
            URLClassLoader urlClassLoader=getUrlClassLoader(name);
            CLASS_LOADER_MAP.remove(name,urlClassLoader);
            ClassLoaderUtil.releaseLoader(urlClassLoader);
        }
    }

    /**
     * 获取当前的UrlClassLoader
     * @return
     */
    public static URLClassLoader getUrlClassLoader(String jarPath) {
        File file=new File(jarPath);
        URLClassLoader urlClassLoader=CLASS_LOADER_MAP.get(file.getName());
        if (urlClassLoader == null){
            throw new RuntimeException("动态加载jar可能出现了异常，导致无法获取UrlClassLoader");
        }
        return urlClassLoader;
    }

    public static Map<String,URLClassLoader> getClassLoaderMap(){
        return CLASS_LOADER_MAP;
    }

}
